package ovm.gui.forms;

import com.vaadin.data.Item;
import com.vaadin.ui.*;
import ovm.gui.selectors.AbstractEntitySelector;
import ovm.management.AbstractManager;
import ovm.management.EntityPropertyCaption;
import ovm.management.EntityTableFormManager;
import ovm.management.users.UserRules;

import java.util.Date;

import static ovm.application.MainApplication.*;
import static ovm.management.AbstractManager.getPropertyClass;

public class AbstractEntityForm extends Form {

    protected Object entity;
    protected Class entityClass;
    protected Boolean editable;

    public class EntityFormFieldFactory implements FormFieldFactory {

        @Override
        public Field createField(Item item, Object propertyId, Component uiContext) {
            Class propertyClass = getPropertyClass(entityClass, (String) propertyId);
            if (propertyClass.equals(String.class) || propertyClass.equals(Integer.class) || propertyClass.equals(int.class)) {
                return new TextField();
            } else if (propertyClass.equals(Date.class)) {
                DateField dateField = new DateField();
                dateField.setDateFormat("dd.MM.yyyy");
                return dateField;
            } else {
                return new AbstractEntitySelector(propertyClass);
            }
        }
    }

    public AbstractEntityForm(Object entity, Boolean editable) {
        super();
        this.entity = entity;
        this.editable = editable;
        this.entityClass = entity.getClass();

        EntityPropertyCaption entityProperties = EntityTableFormManager.getDefaultFormProperties(entityClass);

        setFormFieldFactory(new EntityFormFieldFactory());
        setVisibleItemProperties(entityProperties.getProperties());
        setValue(this.entity);

        for (int i = 0; i < entityProperties.getProperties().length; i++) {
            getField(entityProperties.getProperties()[i]).setCaption(entityProperties.getCaptions()[i]);
            getField(entityProperties.getProperties()[i]).setRequired((entityProperties.getRequired()[i] > 0) ? true : false);
            getField(entityProperties.getProperties()[i]).setDescription(entityProperties.getDescriptions()[i]);
        }

        if (navigator.getCurrentUser() < UserRules.TEACHER) {
            setEnabled(false);
        }

        if (editable) {
            HorizontalLayout toolbar = new HorizontalLayout();
            toolbar.setHeight("30px");
            getFooter().addComponent(toolbar);
            Button commitButton = new Button ("Добавить / Изменить", this, "commit");
            Button discardButton = new Button ("Отмена", this, "discard");
            toolbar.addComponent(commitButton);
            toolbar.setComponentAlignment(commitButton, Alignment.TOP_RIGHT);
            toolbar.addComponent(discardButton);
        }
    }

    @Override
    public void commit() {
        if (AbstractManager.persistAbstractEntity(entity) == AbstractManager.SUCCESSFUL) {
            navigator.showNotification("Сущность успешно изменена или добавлена");
            setVisible(false);
        } else {
            navigator.showNotification("Произошла ошибка при добавлении новой сущности");
        }
    }

    @Override
    public void discard() {
        setVisible(false);
    }

    public Object getEntity() {
        return entity;
    }

    public Class getEntityClass() {
        return entityClass;
    }
    
}
